{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Desempenho básico"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difusão é um processo aleatório que demanda muito processamento. Você pode precisar executar o `DiffusionPipeline` várias vezes antes de obter o resultado desejado. Por isso é importante equilibrar cuidadosamente a velocidade de geração e o uso de memória para iterar mais rápido.\n",
    "\n",
    "Este guia recomenda algumas dicas básicas de desempenho para usar o `DiffusionPipeline`. Consulte a seção de documentação sobre Otimização de Inferência, como [Acelerar inferência](https://huggingface.co/docs/diffusers/main/pt/./optimization/fp16) ou [Reduzir uso de memória](https://huggingface.co/docs/diffusers/main/pt/./optimization/memory) para guias de desempenho mais detalhados."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Uso de memória"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reduzir a quantidade de memória usada indiretamente acelera a geração e pode ajudar um modelo a caber no dispositivo.\n",
    "\n",
    "O método `enable_model_cpu_offload()` move um modelo para a CPU quando não está em uso para economizar memória da GPU."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from diffusers import DiffusionPipeline\n",
    "\n",
    "pipeline = DiffusionPipeline.from_pretrained(\n",
    "  \"stabilityai/stable-diffusion-xl-base-1.0\",\n",
    "  torch_dtype=torch.bfloat16,\n",
    "  device_map=\"cuda\"\n",
    ")\n",
    "pipeline.enable_model_cpu_offload()\n",
    "\n",
    "prompt = \"\"\"\n",
    "cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California\n",
    "highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain\n",
    "\"\"\"\n",
    "pipeline(prompt).images[0]\n",
    "print(f\"Memória máxima reservada: {torch.cuda.max_memory_allocated() / 1024**3:.2f} GB\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Velocidade de inferência"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "O processo de remoção de ruído é o mais exigente computacionalmente durante a difusão. Métodos que otimizam este processo aceleram a velocidade de inferência. Experimente os seguintes métodos para acelerar.\n",
    "\n",
    "- Adicione `device_map=\"cuda\"` para colocar o pipeline em uma GPU. Colocar um modelo em um acelerador, como uma GPU, aumenta a velocidade porque realiza computações em paralelo.\n",
    "- Defina `torch_dtype=torch.bfloat16` para executar o pipeline em meia-precisão. Reduzir a precisão do tipo de dado aumenta a velocidade porque leva menos tempo para realizar computações em precisão mais baixa."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import time\n",
    "from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler\n",
    "\n",
    "pipeline = DiffusionPipeline.from_pretrained(\n",
    "  \"stabilityai/stable-diffusion-xl-base-1.0\",\n",
    "  torch_dtype=torch.bfloat16,\n",
    "  device_map=\"cuda\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Use um agendador mais rápido, como `DPMSolverMultistepScheduler`, que requer apenas ~20-25 passos.\n",
    "- Defina `num_inference_steps` para um valor menor. Reduzir o número de passos de inferência reduz o número total de computações. No entanto, isso pode resultar em menor qualidade de geração."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)\n",
    "\n",
    "prompt = \"\"\"\n",
    "cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California\n",
    "highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain\n",
    "\"\"\"\n",
    "\n",
    "start_time = time.perf_counter()\n",
    "image = pipeline(prompt).images[0]\n",
    "end_time = time.perf_counter()\n",
    "\n",
    "print(f\"Geração de imagem levou {end_time - start_time:.3f} segundos\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Qualidade de geração"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Muitos modelos de difusão modernos entregam imagens de alta qualidade imediatamente. No entanto, você ainda pode melhorar a qualidade de geração experimentando o seguinte.\n",
    "\n",
    "- Experimente um prompt mais detalhado e descritivo. Inclua detalhes como o meio da imagem, assunto, estilo e estética. Um prompt negativo também pode ajudar, guiando um modelo para longe de características indesejáveis usando palavras como baixa qualidade ou desfocado.\n",
    "\n",
    "    ```py\n",
    "    import torch\n",
    "    from diffusers import DiffusionPipeline\n",
    "\n",
    "    pipeline = DiffusionPipeline.from_pretrained(\n",
    "        \"stabilityai/stable-diffusion-xl-base-1.0\",\n",
    "        torch_dtype=torch.bfloat16,\n",
    "        device_map=\"cuda\"\n",
    "    )\n",
    "\n",
    "    prompt = \"\"\"\n",
    "    cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California\n",
    "    highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain\n",
    "    \"\"\"\n",
    "    negative_prompt = \"low quality, blurry, ugly, poor details\"\n",
    "    pipeline(prompt, negative_prompt=negative_prompt).images[0]\n",
    "    ```\n",
    "\n",
    "    Para mais detalhes sobre como criar prompts melhores, consulte a documentação sobre [Técnicas de prompt](https://huggingface.co/docs/diffusers/main/pt/./using-diffusers/weighted_prompts).\n",
    "\n",
    "- Experimente um agendador diferente, como `HeunDiscreteScheduler` ou `LMSDiscreteScheduler`, que sacrifica velocidade de geração por qualidade.\n",
    "\n",
    "    ```py\n",
    "    import torch\n",
    "    from diffusers import DiffusionPipeline, HeunDiscreteScheduler\n",
    "\n",
    "    pipeline = DiffusionPipeline.from_pretrained(\n",
    "        \"stabilityai/stable-diffusion-xl-base-1.0\",\n",
    "        torch_dtype=torch.bfloat16,\n",
    "        device_map=\"cuda\"\n",
    "    )\n",
    "    pipeline.scheduler = HeunDiscreteScheduler.from_config(pipeline.scheduler.config)\n",
    "\n",
    "    prompt = \"\"\"\n",
    "    cinematic film still of a cat sipping a margarita in a pool in Palm Springs, California\n",
    "    highly detailed, high budget hollywood movie, cinemascope, moody, epic, gorgeous, film grain\n",
    "    \"\"\"\n",
    "    negative_prompt = \"low quality, blurry, ugly, poor details\"\n",
    "    pipeline(prompt, negative_prompt=negative_prompt).images[0]\n",
    "    ```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Próximos passos"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Diffusers oferece otimizações mais avançadas e poderosas, como [group-offloading](https://huggingface.co/docs/diffusers/main/pt/./optimization/memory#group-offloading) e [compilação regional](https://huggingface.co/docs/diffusers/main/pt/./optimization/fp16#regional-compilation). Para saber mais sobre como maximizar o desempenho, consulte a seção sobre Otimização de Inferência."
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 4
}
